package com.apes.fn.server.workDesk.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customer.FnAppCustomerService;
import com.apes.fn.serveControl.serverChildPackage.ControlService;
import com.apes.fn.server.pickUpCar.service.PickUpCarDao;
import com.apes.fn.server.servicePlan.repository.ServicePlanDao;
import com.apes.fn.server.workDesk.model.WorkDeskAssistantConfig;
import com.apes.fn.server.workDesk.model.WorkDeskConfig;
import com.apes.fn.server.workDesk.repository.WorkDeskAssistantConfigRepository;
import com.apes.fn.server.workDesk.repository.WorkDeskConfigDao;
import com.apes.fn.server.workDesk.repository.WorkDeskConfigRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.query.SqlService;
import com.apes.framework.rop.session.SimpleSession;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: apes-server
 * @description:
 * @author: czs
 * @create: 2022-07-28 16:06
 **/
@Service("workDeskConfigService")
public class WorkDeskConfigService extends DomainService {

    @Autowired
    WorkDeskConfigRepository workDeskConfigRepository;

    @Autowired
    ControlService controlService;

    @Autowired
    WorkDeskConfigDao workDeskConfigDao;

    @Autowired
    PickUpCarDao pickUpCarDao;

    @Autowired
    ServicePlanDao servicePlanDao;

    @Autowired
    SqlService sqlService;

    @Autowired
    WorkDeskAssistantConfigRepository workDeskAssistantConfigRepository;

    /**
     * 返回在店车辆的状态
     * -入参deptId ,
     * -套用了车辆总控的查询,
     * 所以需要通过配置表过滤需要的状态
     * @param re
     * @return
     */
    public List obtainMainListForWorkDesk(SimpleRequest re){
       //获取总控所有在店车辆状态
        List labelList = getWorkStateResultList(re);
        //过滤需要的状态
        return getConfigResult(labelList,"work_state");
    }

    /**
     * 获取工作台配置需要的在店状态
     * - old -> 原名称
     * - name -> 新名称
     * @param labelList
     * @param type
     * @return
     */
    private List getConfigResult(List labelList,String type) {

        List resultList = new ArrayList();
        workDeskConfigRepository.findAllByTypeAndValidIsTrueOrderByIdAsc(type)
                .forEach(workDeskConfig -> {
                    labelList.forEach(label -> {
                        Map jo = (HashMap) label;
                        Object name = jo.get("name");
                        if (workDeskConfig.getOld().equals(name)) {
                            jo.put("name",workDeskConfig.getName());
                            jo.put("pic",workDeskConfig.getOther());
                            jo.put("formId",workDeskConfig.getData());
                            jo.put("api",workDeskConfig.getApi());
                            jo.put("count_api",workDeskConfig.getCountApi());
                            jo.put("LABEL_TWO",((HashMap) label).get("id"));
                            resultList.add(jo);
                        }
                    });
                });
        sortResultList(resultList);
        return resultList;
    }

    public void sortResultList(List resultList){
        if(resultList.size() > 0) {
            Object item = resultList.remove(0);
            resultList.add(item);
        }else{
            workDeskConfigRepository.findAllByTypeAndValidIsTrueOrderByIdAsc("work_state")
                    .forEach(workDeskConfig -> {
                        Map map = new HashMap<>();
                        map.put("name",workDeskConfig.getName());
                        map.put("pic",workDeskConfig.getOther());
                        map.put("formId",workDeskConfig.getData());
                        map.put("api",workDeskConfig.getApi());
                        map.put("count_api",workDeskConfig.getCountApi());
                        map.put("LABEL_TWO",workDeskConfig.getId());
                        resultList.add(map);
                    });
        }
    }

    /**
     * 入参DEPT_ID 转换格式查询
     * @param re
     * @return
     */
    private List getWorkStateResultList(SimpleRequest re) {
        JSONObject jo1 = re.getJO();
        jo1.put("size",0);
        jo1.put("page",0);
        String dept;
        List<JSONObject> condition = new ArrayList<>();
        List value = new ArrayList();
        if ((dept = getDeptId(re)) != null)
            value.add(dept);
        if(!(dept == null)){
            condition.add(new JSONObject(MapUtil.mapper("field","DEPT_ID_O","operator","IN","value",value)));
            jo1.put("condition",condition);
        }
        re.setData(jo1);
        return controlService.getInStoreCarTypeCount(re);
    }

    /**
     * 常用入口-工作台查询
     * @param re
     * @return
     */
    public List workDeskMenuEntrance(SimpleRequest re){
        return workDeskConfigRepository.findAllByTypeAndValidIsTrueOrderByIdAsc("menu_entrance")
                .stream()
                .sorted(Comparator.comparing(WorkDeskConfig::getLastUpdatedStamp))
                .map(workDeskConfig ->
                        mapper("name",workDeskConfig.getName(),
                                "menuId",workDeskConfig.getData(),
                                "pic",workDeskConfig.getOther(),
                                "id",workDeskConfig.getId(),
                                "count_api",workDeskConfig.getCountApi()))
                .collect(Collectors.toList());
    }


    /**
     * 未完成单据-工作台查询
     * @param re
     * @return
     */
    public List unfinishedWork(SimpleRequest re){
        JSONObject param = new JSONObject();

        try {
            SimpleSession session = re.getSession();
            String postId = session.getPostId();
            Post post = SpringManager.getBean(PostRepository.class).findOne(postId);
            Dept dept = post.getDept();
            param.put("POST",postId);
            if (dept != null)
                param.put("DEPT",dept.getId());
        }catch(Exception e){
            e.printStackTrace();
        }

        //获取需要在工作台展示的单据
        List<WorkDeskConfig> unfinishedWork = workDeskConfigRepository.findAllByTypeAndValidIsTrueOrderByIdAsc("unfinished_work");
        //如果是商户管理层则获取到该商户下所有门店的未完结事项,否则只获取当前部门的数据
        JSONArray systemUseCheckOrderCount = workDeskConfigDao.querySystemUseCheckOrderCountByDept(param);
        //给数据分组
        List resultList = unfinishedWork.stream()
                .filter(workDeskConfig -> workDeskConfig.getOther() == null)
                .map(workDeskConfig ->
                        mapper("name", workDeskConfig.getName(),
                                "context",
                                mapChangeToList(systemUseCheckOrderCount
                                                .stream()
                                                .filter(o -> ((JSONObject) o).getString("OTHER").equals(workDeskConfig.getName()))
                                                .filter(o -> !((JSONObject) o).getString("DEPT_NAME").equals("NONE"))
                                                .collect(Collectors.groupingBy(o -> ((JSONObject) o).getString("DEPT_NAME")))
                                )

                        )
                )
                .collect(Collectors.toList());

        return resultList;
    }

    /**
     * map转list<map>
     * -主要是计算合计
     * @param map
     * @return
     */
    private List<JSONObject> mapChangeToList(Map map){
        List resultList = new ArrayList();
        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            JSONObject jsonObject = new JSONObject();
            Map.Entry<String, List> entry = (Map.Entry)iterator.next();
            List value = entry.getValue();
            jsonObject.put("id",value.stream().map(o -> ((JSONObject)o).getString("DEPT_ID")).findFirst().orElse(null));
            jsonObject.put("name",entry.getKey());
            jsonObject.put("count",value.stream().mapToDouble(o -> ((JSONObject)o).getInteger("COUNT")).sum());
            jsonObject.put("context", value);
            resultList.add(jsonObject);
        }
        return resultList;
    }

    public String getDeptId(SimpleRequest request){
        try {
            SimpleSession session = request.getSession();
            String postId = session.getPostId();
            Post post = SpringManager.getBean(PostRepository.class).findOne(postId);
            Dept dept = post.getDept();
            if (dept != null)
                return dept.getId();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public JSONObject obtainMainListForWorkDeskItem(SimpleRequest re){
        JSONObject jo = re.getJO();
        String label_two = jo.getString("LABEL_TWO");
        JSONArray result = new JSONArray();
        String deptId;
        if ((deptId = getDeptId(re)) != null) jo.put("DEPT_ID",deptId);
        String fz = "";
        switch (label_two){
            case "000429":
                // 待出方案
                result = workDeskConfigDao.workDeskWaitPlan(jo);
                fz = "outScheme";
                break;
            case "000426":
                // 未结算交车
                result = workDeskConfigDao.workDeskNotSettled(jo);
                fz = "schemeState";
                break;
                default:
                    result = workDeskConfigDao.workDeskWaitStartWork(jo);
                    fz = "schemeState";
        }
        JSONObject response = new JSONObject();
        response.put(fz,result);
        return response;
    }

    /**
     * 未完结事项明细
     * @param re
     * @return
     */
    public JSONObject unfinishedWorkItem(SimpleRequest re){
        JSONArray result = workDeskConfigDao.querySystemUseCheckOrderItem(re.getJO());
        JSONObject response = new JSONObject();
        response.put("unfinishedWork",result);
        return response;
    }

    public JSONArray stockInfo(SimpleRequest re){
        JSONArray resultArray = new JSONArray();
        JSONObject jo = re.getJO();
        String deptId;
        if ((deptId = getDeptId(re)) != null) jo.put("DEPT_ID",deptId);
        Map stockWarringMapper = mapper("count",
                workDeskConfigDao.stockWarringRCL(jo).stream().mapToDouble(o -> {
                    JSONObject jsonObject = (JSONObject) o;
                    return jsonObject.getInteger("USABLE_QTY") - jsonObject.getInteger("SAFETY_STOCK_QTY");
                }).sum()
        );
        WorkDeskConfig stockWarring = workDeskConfigRepository.findByType("stock_warring");
        definitionWorkDeskConfig(stockWarringMapper,stockWarring);
        resultArray.add(stockWarringMapper);
        Map unsalableStockMapper = mapper("count",
                workDeskConfigDao.unsalableStockRCL(jo).stream().mapToDouble(o -> {
                    JSONObject jsonObject = (JSONObject) o;
                    return jsonObject.getInteger("USABLE_QTY") - jsonObject.getInteger("SAFETY_STOCK_QTY");
                }).sum()
        );
        WorkDeskConfig stockUnsalable = workDeskConfigRepository.findByType("stock_unsalable");
        definitionWorkDeskConfig(unsalableStockMapper,stockUnsalable);
        resultArray.add(unsalableStockMapper);
        return resultArray;
    }

    public void definitionWorkDeskConfig(Map map,WorkDeskConfig workDeskConfig){
        map.put("api",workDeskConfig.getApi());
        map.put("formId",workDeskConfig.getData());
        map.put("name",workDeskConfig.getName());
        map.put("id",workDeskConfig.getId());
        map.put("count_api",workDeskConfig.getCountApi());
        map.put("pic",workDeskConfig.getOld());
    }

    /**
     * 库存预警
     * @param re
     * @return
     */
    public JSONObject stockWarring(SimpleRequest re){
        JSONObject jo = re.getJO();
        String deptId;
        if ((deptId = getDeptId(re)) != null) jo.put("DEPT_ID",deptId);
        JSONArray result = workDeskConfigDao.stockWarringRCL(jo);
        return getStockResponse(result);
    }

    /**
     * 滞销库存
     * @param re
     * @return
     */
    public JSONObject unsalableStock(SimpleRequest re){
        JSONObject jo = re.getJO();
        String deptId;
        if ((deptId = getDeptId(re)) != null) jo.put("DEPT_ID",deptId);
        JSONArray result = workDeskConfigDao.unsalableStockRCL(jo);
        return getStockResponse(result);
    }

    /**
     * 封装库存预警、滞销的结果
     * @param result
     * @return
     */
    public JSONObject getStockResponse(JSONArray result){
        JSONObject response = new JSONObject();
        response.put("stock",result);
        return response;
    }

    public JSONObject workDeskAssistantDrawer(SimpleRequest re){
        JSONObject result = new JSONObject();
        // 获取弹框查询数据
        com.apestech.framework.json.JSONObject param = getParamByDrawer(re);
        // 弹框数据查询
        com.apestech.framework.json.JSONArray queryResult = queryDrawer(param);
        // 封装结果
        result.put("drawerData",queryResult);
        return result;
    }

    public List workDeskAssistantDisplay(SimpleRequest simpleRequest){
        List<Map> result = null;
        try {
            // 明细
            List<Map> detail = workDeskAssistantDetail(simpleRequest);
            // 分组
            result = workDeskAssistantGroup(detail);
        } catch (Exception e) {
            return null;
        }
        return result;
    }

    public Map workDeskAssistantDisplayByDetail(SimpleRequest re){
        Map detailMap = null;
        try {
            WorkDeskAssistantConfig detail = workDeskAssistantConfigRepository.findOne(re.getJO().getString("detailId"));
            String deptId = getDeptId(re);
            detailMap = new HashMap<>();
            // 封装查询数据
            wrapQueryDate(detailMap,detail,deptId);
            // 封装异常数据
            wrapErrDate(detailMap,detail);
        } catch (Exception e) {
            return null;
        }
        return detailMap;
    }

    private List workDeskAssistantDetail(SimpleRequest re){
        List<WorkDeskAssistantConfig> detailList = workDeskAssistantConfigRepository.findAllByParentIdIsNotNullAndValidIsTrueOrderBySortAsc();
        String deptId = getDeptId(re);
        List result = detailList.stream().map(detail -> {
            Map detailMap = new HashMap();
            // 基本数据
            detailMap.put("detailName",detail.getName());
            detailMap.put("unitName",detail.getUnitName());
            detailMap.put("formId",detail.getFormId());
            detailMap.put("parenId",detail.getParentId());
            detailMap.put("action",detail.getAction());
            detailMap.put("detailId",detail.getId());
            return detailMap;
        }).collect(Collectors.toList());
        return result;
    }

    private void wrapQueryDate(Map detailMap,WorkDeskAssistantConfig detail,String deptId){
        if(detail.getQueryId() == null) return;
        // 封装查询条件
        String paramJSONString = detail.getQueryParam() == null ? "{}" : detail.getQueryParam();
        JSONObject param = JSON.parseObject(paramJSONString);
        if (deptId != null) param.put("DEPT_ID",deptId);
        // 查询
        com.apestech.framework.json.JSONArray queryResult = sqlService.queryId(detail.getQueryId(), new com.apestech.framework.json.JSONObject(param));
        // 封装
        wrapDate(detailMap,detail,queryResult,deptId);
    }

    private void wrapDate(Map detailMap,WorkDeskAssistantConfig detail,com.apestech.framework.json.JSONArray queryResult,String deptId){
        try {
            com.apestech.framework.json.JSONObject jo = queryResult.getJSONObject(0);
            detailMap.put("total",jo.getInteger("TOTAL"));
            // 封装弹框或跳转的条件数据
            if (detail.getConditionModel() != null){
                JSONObject conditionModel = JSON.parseObject(detail.getConditionModel());
                // 封装时间条件
                if (conditionModel.containsKey("DATE") && jo.getInteger("TOTAL") > 0){
                    JSONArray ja = new JSONArray();
                    ja.add(jo.getDate("LTCREATEDATESQL").getTime());
                    ja.add(jo.getDate("GTCREATEDATE").getTime());
                    conditionModel.put(conditionModel.getString("DATE"),ja);
                }
                conditionModel.put("DATE",null);
                if (conditionModel.containsKey("DEPT_ID") && deptId != null) {
                    String key = conditionModel.getString("DEPT_ID");
                    conditionModel.put("DEPT_ID",null);
                    conditionModel.put(key,deptId);
                } else if (conditionModel.containsValue("DEPT_ID") && deptId == null) {
                    conditionModel.put("DEPT_ID",null);
                }
                detailMap.put("condition",conditionModel);
            }
            if ("drawer".equals(detail.getAction())){
                detailMap.put("api","fn.workDeskConfig.assistantDrawer");
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private void wrapErrDate(Map detailMap,WorkDeskAssistantConfig detail){
        if (!detail.isNullErr()
           || (detailMap.get("total") != null && Integer.parseInt(detailMap.get("total").toString()) > 0)) return;
        detailMap.put("msg",detail.getNullErrMsg());
    }

    private List workDeskAssistantGroup(List<Map> detailList){
        List<WorkDeskAssistantConfig> groupList = workDeskAssistantConfigRepository.findAllByParentIdIsNullAndValidIsTrueOrderBySortAsc();
        List result = groupList.stream().map(workDeskAssistantConfig -> {
            Map map = new HashMap();
            map.put("groupName", workDeskAssistantConfig.getName());
            map.put("img", workDeskAssistantConfig.getImg());
            JSONArray detailArray = new JSONArray();
            detailList.forEach(detail -> {
                if(detail.get("parenId").equals(workDeskAssistantConfig.getId())){
                    detailArray.add(detail);
                }
            });
            map.put("detail",detailArray);
            return map;
        }).collect(Collectors.toList());
        return result;
    }

    private com.apestech.framework.json.JSONObject getParamByDrawer(SimpleRequest re){
        JSONObject condition = re.getJO().getJSONObject("condition");
        com.apestech.framework.json.JSONObject param = new com.apestech.framework.json.JSONObject(condition);

        String deptId = getDeptId(re);
        if (deptId != null) param.put("DEPT_ID",deptId);

        param.put("drawer","true");

        return param;
    }

    private com.apestech.framework.json.JSONArray queryDrawer(com.apestech.framework.json.JSONObject param){
        if (param.containsKey("CREATE_DATE_GT")&&param.containsKey("CREATE_DATE_LT")){
            try {
                param.put("CREATE_DATE_GT",param.getDate("CREATE_DATE_GT"));
                param.put("CREATE_DATE_LT",param.getDate("CREATE_DATE_LT"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        com.apestech.framework.json.JSONArray result = sqlService.queryId(param.getString("queryId"), param);
        return result;
    }

    /**
     * 去开单跳转到服务方案单时，若不调用此api，会默认调用服务方案单的api，导致数据丢失
     * @param re
     * @return
     */
    public Map workDeskByDKD(SimpleRequest re){
        // 封装参数
        String licenseNumber = re.getJO().getString("LICENSE_NUMBER");
        List filters = new ArrayList();
        filters.add(MapUtil.mapper("field","realname","operator","LIKE","value",licenseNumber));
        filters.add(MapUtil.mapper("field","carLicense","operator","LIKE","value",licenseNumber));
        filters.add(MapUtil.mapper("field","mobile","operator","LIKE","value",licenseNumber));
        Map group = new HashMap();
        group.put("filters",filters);
        group.put("groups",new ArrayList<>());
        group.put("operator","or");
        Map map = MapUtil.mapper("key",licenseNumber,
                "page",0,
                "size",20,
                "group",group);
        // 调用查询车牌
        Map result = (Map)invoke("fn.customerCar.findAll", map);
        JSONArray ja = (JSONArray)result.get("content");
        if (ja.size() == 0) return null;
        return MapUtil.mapper("fnCustomerExpandTemp1",ja.get(0),"controlDKD",true,"workDeskDKDCreate",true);
    }
}
